package com.sunseen.capacitormachine.modules.home;

import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.SeekBar;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.sunseen.capacitormachine.common.MethodUtil;
import com.sunseen.capacitormachine.commumication.http.HttpUtil;
import com.sunseen.capacitormachine.commumication.http.RestClient;
import com.sunseen.capacitormachine.commumication.tcp.event.DetectedImplosionEvent;
import com.sunseen.capacitormachine.commumication.tcp.event.HolderTemperatureEvent;
import com.sunseen.capacitormachine.R;
import com.sunseen.capacitormachine.commumication.tcp.event.ViEvent;
import com.sunseen.capacitormachine.data.DataUtil;
import com.sunseen.capacitormachine.data.ObjectBox;
import com.sunseen.capacitormachine.databinding.FragmentCapacitorDetailBinding;
import com.sunseen.capacitormachine.common.BaseFragment;
import com.sunseen.capacitormachine.modules.home.bean.XyAxisBean;
import com.sunseen.capacitormachine.modules.query.bean.IVBean;

import java.util.ArrayList;
import java.util.List;

import androidx.databinding.ViewDataBinding;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import io.objectbox.Box;
import io.objectbox.query.QueryBuilder;

/**
 * @author zest
 */
public class CapacitorDetailFragment extends BaseFragment implements CompoundButton.OnCheckedChangeListener {


    private static Handler handler = new Handler();

    private int holderId;
    private int pos;
    private int temp;
    private String uid = "";
    private boolean normal;

    private int total_page = 1;
    private static int page_f = 1;
    private static boolean successRegister = false;
    private static boolean failureRegister = false;
    private static boolean errorRegister = false;

    private static boolean isRefresh = false;
    private static long time_temp = 0;

    public void setData(String uid, int holderId, int pos, boolean normal, int temp) {
        DataUtil.setCurrentCapacitorPos(pos);
        this.holderId = holderId;
        this.uid = uid;
        this.pos = pos;
        this.temp = temp;
        this.normal = normal;
    }

    @Override
    protected int setLayout() {
        return R.layout.fragment_capacitor_detail;
    }

    private XyAxisBean xyAxisBean;
    private Box<XyAxisBean> xyAxisBeanBox;

    private void initXyAxisBean() {
        xyAxisBeanBox = ObjectBox.getBoxStore().boxFor(XyAxisBean.class);
        QueryBuilder<XyAxisBean> queryBuilder = xyAxisBeanBox.query();
        xyAxisBean = queryBuilder.build().findFirst();
        if (xyAxisBean == null) {
            xyAxisBean = new XyAxisBean(600, 3000);
            xyAxisBeanBox.put(xyAxisBean);
        }
    }

    private FragmentCapacitorDetailBinding binding;

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onBindView(ViewDataBinding viewDataBinding) {
        binding = (FragmentCapacitorDetailBinding) viewDataBinding;
        binding.setOnBackClick((view) -> {
            DataUtil.reCoverCurrentCapacitorPos();
            pop();
        });

        binding.tvIdValue.setText(uid);//MethodUtil.getCapacitorId(uid)
        binding.tvCapacitorName.setText(String.format(getString(R.string.capacitor_format), pos + 1));
        binding.tvTempValue.setText(String.format(getString(R.string.temperature_format), temp / 10.0f));
        binding.tvTempValue.setVisibility(View.INVISIBLE);
        binding.tvCapacitorStatus.setText(normal ? "正常" : "内爆");
        binding.cbHolderStatus.setChecked(!normal);
        binding.showHideVoltageCb.setOnCheckedChangeListener(this);
        binding.showHideCurrentCb.setOnCheckedChangeListener(this);
        binding.startPauseCb.setOnCheckedChangeListener(this);
        initXyAxisBean();
        binding.xMaxValueTv.setText(String.valueOf(xyAxisBean.getXMax()));
        binding.xAxisSeekBar.setProgress(xyAxisBean.getXMax() / 60);
        binding.btPreviousPage.setOnClickListener(v -> {
            if(page_f == 1){
                Toast.makeText(getActivity(),"第一页", Toast.LENGTH_SHORT).show();
            } else {
                page_f = page_f - 1;
                if(page_f >= 1 && page_f <= total_page){
                    binding.startPauseCb.setText(R.string.refresh_on_time);
                    pauseMove = true;
                    queryIVData(String.valueOf(page_f), 6000);
                    Toast.makeText(getActivity(),"第"+page_f+"页", Toast.LENGTH_SHORT).show();
                    //Log.e("xiaochunhui: ", "btPreviousPage page_f = " + page_f);
                }
            }
        });
        binding.btNextPage.setOnClickListener(v -> {
            if(page_f == total_page){
                Toast.makeText(getActivity(),"最后一页", Toast.LENGTH_SHORT).show();
                binding.startPauseCb.setChecked(true);//有可能原来是false，导致无法触发change事件
                binding.startPauseCb.setChecked(false);
//                pauseMove = false;
            } else {
                page_f = page_f + 1;
                if(page_f >= 1 && page_f <= total_page){
                    binding.startPauseCb.setText(R.string.refresh_on_time);
                    pauseMove = true;
                    queryIVData(String.valueOf(page_f), 6000);
                    Toast.makeText(getActivity(),"第"+page_f+"页", Toast.LENGTH_SHORT).show();
                    //Log.e("xiaochunhui: ", "btNextPage page_f = " + page_f);
                }
            }
        });
        binding.xAxisSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    xyAxisBean.setXMax(60 * (progress + 1));
                    binding.xMaxValueTv.setText(Integer.toString(xyAxisBean.getXMax()));

                    YAxis yVoltageAxis = binding.lineChart.getAxisLeft();
                    yVoltageAxis.setAxisMaximum(xyAxisBean.getXMax());
                    binding.lineChart.invalidate();
                    binding.lineChart.notifyDataSetChanged();
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                lastPauseMove = pauseMove;
                pauseMove = true;
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                pauseMove = lastPauseMove;
                xyAxisBeanBox.put(xyAxisBean);
            }
        });
        binding.yMaxValueTv.setText(String.valueOf(xyAxisBean.getYMax()));
        binding.yAxisSeekBar.setProgress(xyAxisBean.getYMax() / 150);
        binding.yAxisSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    xyAxisBean.setYMax(150 * (progress + 1));
                    binding.yMaxValueTv.setText(Integer.toString(xyAxisBean.getYMax()));

                    YAxis yCurrentAxis = binding.lineChart.getAxisRight();
                    yCurrentAxis.setAxisMaximum(xyAxisBean.getYMax());
                    binding.lineChart.invalidate();
                    binding.lineChart.notifyDataSetChanged();
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                lastPauseMove = pauseMove;
                pauseMove = true;
                xyAxisBeanBox.put(xyAxisBean);
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                pauseMove = lastPauseMove;
            }
        });

        LineChart lineChart = binding.lineChart;
        lineChart.setNoDataText("");
        lineChart.getDescription().setEnabled(false);
        lineChart.setPinchZoom(true);
        lineChart.setBackgroundColor(Color.TRANSPARENT);

        Legend legend = lineChart.getLegend();
        legend.setForm(Legend.LegendForm.CIRCLE);
        legend.setTextSize(17f);
        legend.setTextColor(Color.BLACK);
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(true);
        legend.setXOffset(-30f);
        legend.setYOffset(-20f);

        XAxis xAxis = lineChart.getXAxis();
        xAxis.setAxisLineColor(getResources().getColor(R.color.colorAccent));
        xAxis.setAxisLineWidth(3f);
        xAxis.setTextSize(15f);
        xAxis.setTextColor(Color.BLACK);
        xAxis.setDrawGridLines(false);
        xAxis.setDrawAxisLine(true);
        xAxis.setAxisMinimum(0f);
        xAxis.mAxisRange = 1200;
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setValueFormatter(new ValueFormatter() {
            @Override
            public String getAxisLabel(float value, AxisBase axis) {
                if (value != 0f) {
                    return (int) value + "s";
                } else {
                    return "";
                }
            }
        });

        YAxis leftAxis = lineChart.getAxisLeft();
        leftAxis.setAxisLineColor(getResources().getColor(R.color.green));
        leftAxis.setTextSize(15f);
        leftAxis.setAxisLineWidth(2f);
        leftAxis.setAxisMaximum(xyAxisBean.getXMax());
        leftAxis.setAxisMinimum(0f);
        leftAxis.setDrawGridLines(false);
        leftAxis.setGranularityEnabled(false);

        YAxis rightAxis = lineChart.getAxisRight();
        rightAxis.setAxisLineColor(getResources().getColor(R.color.red_light));
        rightAxis.setTextSize(15f);
        rightAxis.setAxisLineWidth(2f);
        rightAxis.setAxisMaximum(xyAxisBean.getYMax());
        rightAxis.setAxisMinimum(0f);
        rightAxis.setDrawGridLines(false);
        rightAxis.setGranularityEnabled(false);

        if (uid != null && !uid.isEmpty()) {
            queryIVData("last", 6000);
            binding.startPauseCb.setChecked(true);//有可能原来是false，导致无法触发change事件
            binding.startPauseCb.setChecked(false);
        } else {
            initChart();
            EventBus.getDefault().register(this);
        }
    }

    private void queryIVData(String page, int perPage) {
        hideProgressBar(false);
        RestClient.builder().url(HttpUtil.ivData)
                .params("uid", uid)
                .params("page", page)
                .params("per_page", perPage)
                .success((String response) -> {
//                    MethodUtil.loge("xiaochunhui:", "-" + response);
                    JSONObject jsonObject = JSON.parseObject(response);
                    if (jsonObject.getInteger("status") == 1) {
                        JSONObject dataObj = jsonObject.getJSONObject("data");
                        if (dataObj != null) {
//                            JSONArray jsonArray = dataObj.getJSONArray("array");
                            String str = dataObj.getString("array");
                            List<IVBean> ivBeanList = null;
                            if(!TextUtils.isEmpty(str)){
                                JSONArray jsonArray = JSON.parseArray(str);
                                ivBeanList = jsonArray.toJavaList(IVBean.class);
                                //          MethodUtil.loge("xiaochunhui:", "-" + str);
                                total_page = dataObj.getInteger("total_page");
                                Log.e("xiaochunhui: ", "total_page = " + total_page);
                                Log.e("xiaochunhui: ", "ivBeanList.size() = " + ivBeanList.size());
                                Log.e("xiaochunhui: ", "total_count = " + dataObj.getInteger("total_count"));
                            }
//                            MethodUtil.loge("xiaochunhui", "-" + jsonArray.toJSONString());
                            if (ivBeanList != null && ivBeanList.size() > 0) {
                                initChart(ivBeanList);
                                try {
                                    page_f = Integer.valueOf(page);
                                }catch (NumberFormatException e){
                                    page_f = total_page;
                                }

                            } else {
                                initChart();
                                Toast.makeText(_mActivity, "无电流电压数据", Toast.LENGTH_SHORT).show();
                            }
                        } else {
                            initChart();
                            Toast.makeText(_mActivity, "查询电流电压数据失败", Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        initChart();
                        Toast.makeText(_mActivity, "查询电流电压数据失败", Toast.LENGTH_SHORT).show();
                    }
                    if(!successRegister) {
                        successRegister = true;
                        EventBus.getDefault().register(this);
                    }

                    hideProgressBar(true);
                })
                .failure(() -> {
                    if (!popPressed) {
                        hideProgressBar(true);
                        initChart();
                        if(!failureRegister){
                            EventBus.getDefault().register(CapacitorDetailFragment.this);
                        }

                        Toast.makeText(_mActivity, "查询电流电压数据失败", Toast.LENGTH_SHORT).show();
                    }
                })
                .error((int code, String msg) -> {
                    if (!popPressed) {
                        hideProgressBar(true);
                        initChart();
                        if(!errorRegister) {
                            //EventBus.getDefault().isRegistered() 可以尝试用这个
                            EventBus.getDefault().register(CapacitorDetailFragment.this);
                        }

                        Toast.makeText(_mActivity, "查询电流电压数据错误", Toast.LENGTH_SHORT).show();
                        Log.e("test", "code = " + code + " msg = " + msg);
                    }
                })
                .build()
                .get();
    }

    private void hideProgressBar(boolean hide) {
        binding.loadingLineDataProgress.setVisibility(hide ? View.GONE : View.VISIBLE);
        binding.loadingTip.setVisibility(hide ? View.GONE : View.VISIBLE);
    }

    private LineData lineData;
    private LineDataSet set1;
    private LineDataSet set2;

    private void initChart(List<IVBean> ivBeanList) {
        List<Entry> list1 = new ArrayList<>();
        List<Entry> list2 = new ArrayList<>();
        for (int i = 0, size = ivBeanList.size(); i < size; i++) {
            IVBean ivBean = ivBeanList.get(i);
            list1.add(new Entry(i, ivBean.getV()));
            list2.add(new Entry(i, ivBean.getI()));
        }
        set1 = new LineDataSet(list1, "");
        set1.setAxisDependency(YAxis.AxisDependency.LEFT);
        int greenColor = getResources().getColor(R.color.green);
        set1.setColor(greenColor);
        set1.setCircleColor(greenColor);
        set1.setLineWidth(2f);
        set1.setCircleRadius(1f);
        set1.setFillColor(greenColor);
        set1.setHighLightColor(Color.rgb(244, 177, 177));
        set1.setDrawCircleHole(false);

        set2 = new LineDataSet(list2, "");
        set2.setAxisDependency(YAxis.AxisDependency.RIGHT);
        int redColor = getResources().getColor(R.color.red_light);
        set2.setColor(redColor);
        set2.setCircleColor(redColor);
        set2.setMode(LineDataSet.Mode.LINEAR);
        set2.setLineWidth(2f);
        set2.setCircleRadius(1f);
        set2.setFillColor(redColor);
        set2.setHighLightColor(Color.rgb(244, 177, 177));
        set2.setDrawCircleHole(false);

        lineData = new LineData(set1, set2);
        lineData.setValueTextColor(Color.BLACK);
        lineData.setValueTextSize(13f);
        binding.lineChart.setData(lineData);
        binding.lineChart.setVisibleXRangeMaximum(1200);
        binding.lineChart.moveViewToX(set1.getEntryCount());
        binding.showHideCurrentCb.setEnabled(true);
        binding.showHideVoltageCb.setEnabled(true);
        binding.xAxisSeekBar.setEnabled(true);
        binding.yAxisSeekBar.setEnabled(true);
    }

    private void initChart() {
        List<Entry> list1 = new ArrayList<>();
        list1.add(new Entry(0, 0));
        List<Entry> list2 = new ArrayList<>();
        list2.add(new Entry(0, 0));
        set1 = new LineDataSet(list1, "");
        set1.setAxisDependency(YAxis.AxisDependency.LEFT);
        int greenColor = getResources().getColor(R.color.green);
        set1.setColor(greenColor);
        set1.setCircleColor(greenColor);
        set1.setLineWidth(2f);
        set1.setCircleRadius(1f);
        set1.setFillColor(greenColor);
        set1.setHighLightColor(Color.rgb(244, 177, 177));
        set1.setDrawCircleHole(false);

        set2 = new LineDataSet(list2, "");
        set2.setAxisDependency(YAxis.AxisDependency.RIGHT);
        int redColor = getResources().getColor(R.color.red_light);
        set2.setColor(redColor);
        set2.setCircleColor(redColor);
        set2.setMode(LineDataSet.Mode.LINEAR);
        set2.setLineWidth(2f);
        set2.setCircleRadius(1f);
        set2.setFillColor(redColor);
        set2.setHighLightColor(Color.rgb(244, 177, 177));
        set2.setDrawCircleHole(false);
        lineData = new LineData(set1, set2);
        lineData.setValueTextColor(Color.BLACK);
        lineData.setValueTextSize(13f);
        binding.lineChart.setData(lineData);
        binding.lineChart.invalidate();
        binding.showHideCurrentCb.setEnabled(true);
        binding.showHideVoltageCb.setEnabled(true);
        binding.xAxisSeekBar.setEnabled(true);
        binding.yAxisSeekBar.setEnabled(true);
    }

    private boolean pauseMove = false;
    private boolean lastPauseMove = false;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onViEvent(ViEvent event) {
        Log.e("test", "onViEvent: v = " + event.getV());
        if (!popPressed) {
            set1.addEntry(new Entry(set1.getEntryCount(), event.getV()));
            set2.addEntry(new Entry(set2.getEntryCount(), event.getI()));
            if (!pauseMove) {
                lineData.notifyDataChanged();
                binding.lineChart.notifyDataSetChanged();
                binding.lineChart.setVisibleXRangeMaximum(1200);
                binding.lineChart.moveViewToX(set1.getEntryCount());
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onDetectedImplosionEvent(DetectedImplosionEvent event) {
        if (holderId == event.getHolderId() && pos == event.getPos()) {
            if (!binding.cbHolderStatus.isChecked()) {
                binding.cbHolderStatus.setChecked(true);
                binding.tvCapacitorStatus.setText("内爆");
            }
        }
    }

    private int lastTemp = 0;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onTemperatureEvent(HolderTemperatureEvent event) {
        if (Math.abs(event.getTemperature() - lastTemp) > 1) {
            binding.tvTempValue.setText(String.format(getString(R.string.temperature_format),
                    event.getTemperature() / 10.0f));
            lastTemp = event.getTemperature();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        page_f = 1;
        successRegister = false;
        failureRegister = false;
        errorRegister = false;
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        switch (buttonView.getId()) {
            case R.id.show_hide_voltage_cb: {
                final boolean lastPause = pauseMove;
                pauseMove = true;
                binding.showHideVoltageCb.setEnabled(false);
                binding.showHideCurrentCb.setEnabled(false);
                hideProgressBar(false);
                if (isChecked) {
                    lineData.addDataSet(set1);
                } else {
                    lineData.removeDataSet(set1);
                }
                binding.lineChart.invalidate();
                handler.postDelayed(() -> {
                    hideProgressBar(true);
                    binding.showHideVoltageCb.setEnabled(true);
                    binding.showHideCurrentCb.setEnabled(true);
                    if (!lastPause) {
                        pauseMove = false;
                    }
                }, 1500);
            }
            break;
            case R.id.show_hide_current_cb: {
                final boolean lastPause = pauseMove;
                pauseMove = true;
                buttonView.setEnabled(false);
                binding.showHideVoltageCb.setEnabled(false);
                binding.showHideCurrentCb.setEnabled(false);
                hideProgressBar(false);
                if (isChecked) {
                    lineData.addDataSet(set2);
                } else {
                    lineData.removeDataSet(set2);
                }
                binding.lineChart.invalidate();
                handler.postDelayed(() -> {
                    hideProgressBar(true);
                    buttonView.setEnabled(true);
                    binding.showHideVoltageCb.setEnabled(true);
                    binding.showHideCurrentCb.setEnabled(true);
                    if (!lastPause) {
                        pauseMove = false;
                    }
                }, 1500);
            }
            break;
            case R.id.start_pause_cb: {
                pauseMove = isChecked;
                buttonView.setText(isChecked ? R.string.refresh_on_time : R.string.pause_refresh);
//                if(pauseMove){
//                    queryIVData("last",6000);
//                }
            }
            break;
        }
    }
}
